﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.Win32;

namespace DiskSpace
{
    public partial class Settings : Form, IConfig
    {
        private Int32 m_spaceAlarmThreshold;
        private Int32 m_spaceWarningThreshold;
        private bool m_displayDiskLabels;
        private bool m_autoStart;

        /// <summary>
        /// Registry key for handling autostart of applications
        /// </summary>
        private RegistryKey rkApp = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);

        /// <summary>
        /// 
        /// </summary>
        public Settings()
        {
            InitializeComponent();

            LoadConfiguration();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Settings_Shown(object sender, EventArgs e)
        {
            tbSpaceAlarmThreshold.Text = m_spaceAlarmThreshold.ToString();
            tbSpaceWarningThreshold.Text = m_spaceWarningThreshold.ToString();
            cbShowDiskLabels.Checked = m_displayDiskLabels;
            cbIncludeRemoveable.Checked = m_includeRemoveable;
            cbIncludeNetwork.Checked = m_includeNetwork;
        }

        /// <summary>
        /// Takes a reference to a context menu and populates with configuration/settings options.
        /// </summary>
        /// <param name="menu">Context menu to populate with items</param>
        public void PopulateMenu(ContextMenu menu)
        {
            // prepare the update time menu
            MenuItem menuItemUpdateTime = new MenuItem("Update Time (secs)");
            menuItemUpdateTime.MenuItems.Add(new MenuItem("1", UpdateTimeHandler));
            menuItemUpdateTime.MenuItems.Add(new MenuItem("5", UpdateTimeHandler));
            menuItemUpdateTime.MenuItems.Add(new MenuItem("10", UpdateTimeHandler));
            menuItemUpdateTime.MenuItems.Add(new MenuItem("20", UpdateTimeHandler));
            // TODO need to figure out a more generic way of checking the item we want
            menuItemUpdateTime.MenuItems[2].Checked = true;
            menu.MenuItems.Add(menuItemUpdateTime);

            MenuItem menuItemIncludeRemoveable = new MenuItem("Include Removeable", IncludeRemovableHandler);
            menuItemIncludeRemoveable.Checked = m_includeRemoveable;
            menu.MenuItems.Add(menuItemIncludeRemoveable);

            MenuItem menuItemAutoStart = new MenuItem("Start on Login", ConfigureAutoStartHandler);
            menuItemAutoStart.Checked = m_autoStart;
            menu.MenuItems.Add(menuItemAutoStart);

            menu.MenuItems.Add(new MenuItem("Settings", SettingsHandler));
        }

        /// <summary>
        /// 
        /// </summary>
        private bool m_includeRemoveable;
        public bool IncludeRemoveable
        {
            get
            {
                return m_includeRemoveable;
            }
            set
            {
                m_includeRemoveable = value;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        private bool m_includeNetwork;
        public bool IncludeNetwork
        {
            get
            {
                return m_includeNetwork;
            }
            set
            {
                m_includeNetwork = value;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        private Int32 m_updateDate;
        public Int32 UpdateTime
        {
            set { m_updateDate = value; }
            get { return m_updateDate; }
        }

        /// <summary>
        /// 
        /// </summary>
        public Int32 AlarmThreshold
        {
            get { return m_spaceAlarmThreshold; }
        }

        /// <summary>
        /// 
        /// </summary>
        public Int32 WarningThreshold
        {
            get { return m_spaceWarningThreshold; }
        }

        /// <summary>
        /// 
        /// </summary>
        public bool DisplayDiskLabels
        {
            get { return m_displayDiskLabels; }
        }
        
        /// <summary>
        /// 
        /// </summary>
        public void SaveConfiguration()
        {
        }

        /// <summary>
        /// 
        /// </summary>
        public void LoadConfiguration()
        {
            m_spaceAlarmThreshold = 95;
            m_spaceWarningThreshold = 75;
            m_includeRemoveable = true;
            m_displayDiskLabels = true;
            m_includeNetwork = false;

            // check if set to auto-run in registry
            if (rkApp.GetValue(Application.ProductName.ToString()).ToString() != Application.ExecutablePath.ToString())
            {
                m_autoStart = false;
            }
            else
            {
                m_autoStart = true;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="percentage"></param>
        /// <returns></returns>
        private Int32 ValidatePercentage(Int32 percentage)
        {
            percentage = percentage < 0 ? 0 : percentage;
            percentage = percentage > 100 ? 100 : percentage;

            return percentage;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void SettingsHandler(object sender, EventArgs e)
        {
            if (this.Visible == false)
            {
                ShowDialog();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void UpdateTimeHandler(object sender, EventArgs e)
        {
            MenuItem mi = (MenuItem)sender;

            Int32 updateTime = 0;

            foreach (MenuItem tmi in mi.Parent.MenuItems)
            {
                if (tmi.Index == mi.Index)
                {
                    tmi.Checked = true;
                }
                else
                {
                    tmi.Checked = false;
                }
            }

            updateTime = Convert.ToInt32(mi.Text.ToString()) * 1000;
            this.UpdateTime = updateTime;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void IncludeRemovableHandler(object sender, EventArgs e)
        {
            MenuItem mi = (MenuItem)sender;
            
            mi.Checked = !mi.Checked;

            m_includeRemoveable = mi.Checked;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void ConfigureAutoStartHandler(object sender, EventArgs e)
        {
            MenuItem mi = (MenuItem)sender;

            m_autoStart = !m_autoStart;
            mi.Checked = m_autoStart;

            if (m_autoStart == true)
            {
                rkApp.SetValue(Application.ProductName.ToString(), Application.ExecutablePath.ToString());
            }
            else
            {
                if(rkApp.GetValue(Application.ProductName.ToString()) != null)
                {
                    rkApp.DeleteValue(Application.ProductName.ToString());
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void bCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void bSave_Click(object sender, EventArgs e)
        {
            m_spaceAlarmThreshold = Convert.ToInt16(tbSpaceAlarmThreshold.Text);
            m_spaceWarningThreshold = Convert.ToInt16(tbSpaceWarningThreshold.Text);
            m_spaceAlarmThreshold = ValidatePercentage(m_spaceAlarmThreshold);
            m_spaceWarningThreshold = ValidatePercentage(m_spaceWarningThreshold);

            if (m_spaceWarningThreshold > m_spaceAlarmThreshold)
            {
                m_spaceWarningThreshold = m_spaceAlarmThreshold;
            }

            m_displayDiskLabels = cbShowDiskLabels.Checked;
            m_includeNetwork = cbIncludeNetwork.Checked;
            m_includeRemoveable = cbIncludeRemoveable.Checked;

            SaveConfiguration();

            Close();
        }
    }
}
